package com.tuanzi.loan.business.service.system.impl;

import static com.google.common.base.Preconditions.checkArgument;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.RetryException;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Maps;
import com.tuanzi.loan.business.entity.system.FunctionalPermission;
import com.tuanzi.loan.business.repository.system.FunctionalPermissionRelationRepository;
import com.tuanzi.loan.business.repository.system.FunctionalPermissionRepository;
import com.tuanzi.loan.business.service.system.FunctionalPermissionService;
import com.tuanzi.loan.core.aspect.Debug;
import com.tuanzi.loan.core.exception.SystemException;
import com.tuanzi.loan.core.repository.JPABaseRepository;
import com.tuanzi.loan.core.service.BaseServiceImpl;

/**
 * @author Ray 2017/09/21
 */
@Debug
@Service
@Transactional
@Retryable(value = { RetryException.class })
public class FunctionalPermissionServiceImpl extends BaseServiceImpl<FunctionalPermission, String> implements FunctionalPermissionService {

	@Autowired
	private FunctionalPermissionRepository functionalPermissionRepository;
	@Autowired
	private FunctionalPermissionRelationRepository functionalPermissionRelationRepository;

	private static Map<String /* code */, String/* name */> FREQUENT_PERMISSIONS;

	static {
		FREQUENT_PERMISSIONS = Maps.newHashMap();
		FREQUENT_PERMISSIONS.put("_SEARCH", "查询");
		FREQUENT_PERMISSIONS.put("_ADD", "新增");
		FREQUENT_PERMISSIONS.put("_EDIT", "编辑");
		FREQUENT_PERMISSIONS.put("_DELETE", "删除");
		FREQUENT_PERMISSIONS = Collections.unmodifiableMap(FREQUENT_PERMISSIONS);
	}

	@Override
	protected JPABaseRepository<FunctionalPermission, String> getRepository() {
		return functionalPermissionRepository;
	}

	@Override
	public void generateFrequentPermission(FunctionalPermission root) {
		for (Map.Entry<String/* code */, String /* name */> entry : FREQUENT_PERMISSIONS.entrySet()) {

			FunctionalPermission functionalPermission = new FunctionalPermission();
			functionalPermission.setName(entry.getValue());
			functionalPermission.setCode(root.getCode() + entry.getKey());
			functionalPermission.setEnable(true);
			functionalPermission.setParentId(root.getId());

			List<FunctionalPermission> existingPermissions = functionalPermissionRepository.findByCode(functionalPermission.getCode());

			if (CollectionUtils.isNotEmpty(existingPermissions)) {
				// 已有相同的code存在, 假定已生成对应的常用权限
				continue;
			}

			functionalPermissionRepository.save(functionalPermission);

		}
	}

	@Override
	public List<FunctionalPermission> findAllPermissionByUserId(String userId) {
		return functionalPermissionRepository.findAllPermissionByUserId(userId);
	}

	@Override
	public void recurseDelete(FunctionalPermission root) {
		checkArgument(root != null && root.getId() != null);

		List<FunctionalPermission> functionalPermissions = functionalPermissionRepository.findAllByParentId(root.getId());

		if (CollectionUtils.isNotEmpty(functionalPermissions)) {
			functionalPermissions.parallelStream().forEach(this::recurseDelete);
		}
		functionalPermissionRelationRepository.deleteInBatch(functionalPermissionRelationRepository.findAllByPermissionId(root.getId()));
		functionalPermissionRepository.delete(root.getId());
	}

	@Override
	public void movePermission(FunctionalPermission from, FunctionalPermission to) {
		from.setParentId(to.getId());
		this.saveOrUpdate(from);
	}

	@Override
	public FunctionalPermission saveOrUpdate(FunctionalPermission functionalPermission) {

		List<FunctionalPermission> existingPermissions = functionalPermissionRepository.findByCode(functionalPermission.getCode());

		if (CollectionUtils.isNotEmpty(existingPermissions)) {

			checkArgument(existingPermissions.size() == 1);

			String existingPermissionId = existingPermissions.get(0).getId();
			if (StringUtils.isBlank(functionalPermission.getId()) || !StringUtils.equals(existingPermissionId, functionalPermission.getId())) {
				throw new SystemException("已存在相同的权限编码");
			}

		}
		return super.saveOrUpdate(functionalPermission);
	}
}
